﻿using System;
using System.Threading;
using System.Threading.Tasks;

namespace _2._5.使用CountdownEvent类
{
    class Program
    {
        //它是一个同步基元，它在收到一定次数的信号之后，将会解除对其等待线程的锁定。
        static CountdownEvent _event = new CountdownEvent(3);

        static CountdownEvent _eventForTask = new CountdownEvent(4);
        static void Test(int seconds,CountdownEvent @event)
        {
            Console.WriteLine($"{Thread.CurrentThread.Name} {Thread.CurrentThread.ManagedThreadId}线程开始执行...");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            Console.WriteLine($"{Thread.CurrentThread.Name} {Thread.CurrentThread.ManagedThreadId} 线程执行完成！") ;
            //定义次数有4次，Signal不能大于定义，否则报异常InvalidOperationException
            @event.Signal();
        }

        static void Main(string[] args)
        {
            TaskTest();
            //ThreadTest();
        }

        static void  ThreadTest()
        {
            Thread t1 = new Thread(() => { Test(2,_event); });
            t1.Name = "t1";
            Thread t2 = new Thread(() => { Test(4,_event); });
            t2.Name = "t2";
            Thread t3 = new Thread(() => { Test(6,_event); });
            t3.Name = "t3";

            t1.Start();
            t2.Start();
            t3.Start();

            //集齐3个信号量才会解除等待
            _event.Wait();
            Console.WriteLine("所有的线程执行完毕！");
            _event.Dispose();

            Console.ReadKey();
        }

        static void TaskTest()
        {
            var tFactory = new TaskFactory();

         
            Task t1 = tFactory.StartNew(() => {
               Test(5,_eventForTask);
            });

            Task t2 = tFactory.StartNew(() => {
                Test(8, _eventForTask);
            });

            Task t3 = tFactory.StartNew(() => {
                Test(10, _eventForTask);
            });

            Task t4= tFactory.StartNew(() => {
                Test(4, _eventForTask);
            });

            Console.WriteLine("等待信号量");
            _eventForTask.Wait();

            Console.WriteLine("所有的Task执行完毕");

            Console.ReadKey();
        }
    }
}
